package cn.mw.cmdb.entity;

import cn.mw.cmdb.param.ImportContextParam;
import cn.mw.cmdb.param.InstanceSearchParam;
import cn.mw.cmdb.service.impl.CmdbServiceManage;
import cn.mw.cmdb.service.impl.CustomModelServiceImpl;
import cn.mw.cmdb.service.impl.InstanceServiceImpl;
import cn.mw.components.mongodb.entity.CriteriaOpsType;
import cn.mw.microMonitorCommon.entity.cmdb.ModelExportDataInfoParam;
import cn.mw.microMonitorCommon.entity.cmdb.MwImportResultParam;
import cn.mw.microMonitorCommon.util.SpringUtils;
import com.alibaba.fastjson.JSONArray;
import com.google.common.base.Strings;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import static cn.mw.cmdb.entity.PropertyTypeEnumSingle.defaultValueKey;
import static cn.mw.cmdb.entity.PropertyTypeEnumSingle.enumInfoListKey;
import static cn.mw.cmdb.service.impl.InstanceViewImpl.*;

@Slf4j
public class PropertyTypeEnumMultiple extends PropertyType<PropertyTypeEnumMultiple, Object> {
    public static final String ID = "enumMultiple";
    private static final String FirstDropdownKey = "modelId";
    //枚举下拉数据
    private List enumInfoList;

    private static List<String> finalList = new ArrayList<>();

    private static final String SecodDropdownKey = "fieldId";

    public PropertyTypeEnumMultiple() {
        setId(ID);
        setName("枚举类型(多选)");
        setSortNum(10);
    }

    @Override
    public Object tableHeaderTipInfo(PropertyTypeRef propertyTypeRef) {
        String tipInfo = "";
        if (propertyTypeRef != null) {
            Map<String, Object> context = propertyTypeRef.getContext();
            Object obj = context.get(enumInfoListKey);
            Object defaultVal = context.get(defaultValueKey);
            if (obj != null && obj instanceof List) {
                List<String> listStr = (List<String>) obj;
                tipInfo += String.join(",", listStr);
                if (defaultVal != null && defaultVal instanceof List) {
                    List<String> defaultValListStr = (List<String>) defaultVal;
                    tipInfo += ";默认值:" + String.join(",", defaultValListStr) + ";";
                }
            }
        }
        tipInfo += "多个数据用“,”隔开";
        return tipInfo;
    }

    @Override
    public Criteria doCriteria(CriteriaOpsType opsType, String name, Object value) {
        Criteria criteria = null;
        switch (opsType) {
            case is:
            case in:
                criteria = new Criteria(name).in(value);
                break;
            case nin:
                criteria = new Criteria(name).nin(value);
                break;
            case elemMatch:
                criteria = new Criteria(name).elemMatch(new Criteria().in(JSONArray.parse(strValueConvert(value))));
                break;
            case exist:
                criteria = new Criteria(name).exists((boolean) value);
                break;
            case ne:
                criteria = new Criteria(name).ne(value);
        }
        return criteria;
    }

    @Override
    public CriteriaOpsType getDefaultCriteriaOpsType() {
        return CriteriaOpsType.is;
    }

    @Override
    public PropertyTypeEnumMultiple newObj() {
        return new PropertyTypeEnumMultiple();
    }

    @Override
    public Object listInputOption(PropertyTypeRef propertyTypeRef) throws Exception {
        Map<String, Object> context = propertyTypeRef.getContext();
        List<InstanceInputOption> list = new ArrayList<>();
        if (null != context) {
            CmdbServiceManage cmdbServiceManage = SpringUtils.getBean(CmdbServiceManage.class);
            InstanceServiceImpl instanceService = (InstanceServiceImpl) cmdbServiceManage.getModelService(InstanceServiceImpl.ID);
            InstanceSearchParam searchParam = new InstanceSearchParam();

            String modelId = context.get(FirstDropdownKey).toString();
            String propertyId = context.get(SecodDropdownKey).toString();

            if (StringUtils.hasText(modelId)) {
                searchParam.setModelId(modelId);
                List<InstanceInfo> instanceInfoList = instanceService.selectList(searchParam);
                if (StringUtils.hasText(propertyId) && null != instanceInfoList) {
                    for (InstanceInfo instanceInfo : instanceInfoList) {
                        InstanceInputOption inputOption = new InstanceInputOption(instanceInfo.getId(), instanceInfo.getValue(propertyId).toString());
                        list.add(inputOption);
                    }
                } else {
                    CustomModelServiceImpl customModelService = (CustomModelServiceImpl) cmdbServiceManage.getModelService(CustomModelServiceImpl.ID);
                    List<ModelInfo> modelInfos = customModelService.findAllList();
                    for (ModelInfo modelInfo : modelInfos) {
                        InstanceInputOption inputOption = new InstanceInputOption(modelInfo.getId(), modelInfo.getModelName());
                        list.add(inputOption);
                    }
                }
            }
        }

        return list;
    }

    public boolean tableHeaderInfo(Map ms, PropertyInfo propertyInfo, List<String> labelNames, List<String> labelId) {
        //导出表头数据时，表头字段的id和名称不能同时重复
        if ((labelId != null && !labelId.contains(propertyInfo.getId())) && (labelNames != null && !labelNames.contains(ms.get(nameKey)))) {
            ms.put(typeKey, PropertyTypeEnumSingle.ID);
            if (propertyInfo.getPropertyTypeRef() != null) {
                PropertyTypeRef propertyTypeRef = propertyInfo.getPropertyTypeRef();
                Map<String, Object> context = propertyTypeRef.getContext();
                Object obj = context.get(enumInfoListKey);
                if (obj != null && obj instanceof List) {
                    List<String> listStr = (List<String>) obj;
                    ms.put(selectDataKey, listStr);
                }
                labelId.add(propertyInfo.getId());
                return true;
            }
        }
        return false;
    }


    /**
     * 导出数据转换
     *
     * @param val
     * @param context
     * @return
     */
    @Override
//    @Override
    public Object exportValue(Object val, Map<String, Object> context) {
        String str = "";
        if (val != null && val instanceof List) {
            if (!CollectionUtils.isEmpty((List) val)) {
                str = String.join(",", (List) val);
            }
        }
        return str;
    }


    @Override
    public Object lookValue(Object val, Map<String, Object> context) {
        if (val != null && val instanceof List) {
            if (!CollectionUtils.isEmpty((List) val)) {
                return (List)val;
            }
        }
        return val;
    }

    @Override
    public void refresh() {
        finalList.clear();
    }


    /**
     * 获取新增字段所需要的配置数据
     *
     * @param val
     * @param context
     * @return
     */
    @Override
    public Object getDefaultInputValue(Object val, Map<String, Object> context) {
        if (context != null) {
            return context;
        }
        return null;
    }

    @Override
    public Object getDataValue(ImportContextParam contextParam) {
        MwImportResultParam resultParam = new MwImportResultParam();
        String message = "";
        ModelExportDataInfoParam importParam = contextParam.getParam();
        //属性名称
        String tableName = importParam.getTableName();
        Object cellValue = importParam.getCellValue();
        Map<String, Object> matchMap = new HashMap<>();
        List<String> defaultValList = null;
        List<String> listStr = new ArrayList<>();
        importCheckInfo(resultParam, contextParam, matchMap);
        if (matchMap != null) {
            //枚举下拉值
            Object obj = matchMap.get(enumInfoListKey);
            //默认值
            Object defaultVal = matchMap.get(defaultValueKey);
            if (obj != null && obj instanceof List) {
                listStr = (List<String>) obj;
            }
            if (defaultVal != null && defaultVal instanceof List) {
                defaultValList = (List<String>) defaultVal;
            }
        }
        boolean isDefaultFlag = false;
        //数值类型为空字符串，默认为0
        if (Strings.isNullOrEmpty(strValueConvert(cellValue).trim())) {
            //默认值存在
            if (!CollectionUtils.isEmpty(defaultValList)) {
                isDefaultFlag = true;
                cellValue = defaultValList;
            } else {
                return resultParam;
            }
        }
        //是否默认值提示
        String prefixStr = prefixStrKey;
        if (isDefaultFlag) {
            prefixStr = defaultPrefixStrKey;
        }

        log.info(tableName + ":enumMultipleOldValue::" + cellValue);
        List<String> listCell = new ArrayList<>();
        if (cellValue != null && cellValue instanceof List) {
            listCell = (List) cellValue;
            for (String str : listCell) {
                if (!listStr.contains(str)) {
                    message += tableName + prefixStr + str + "]枚举值不存在";
                }
            }
        }
        resultParam.setMessage(message);
        log.info(tableName + ":enumMultipleNewValue::" + listCell);
        resultParam.setCellValue(listCell);
        return resultParam;
    }
}
